#pragma once

#include "types.h"
#include "display/display-object.h"
#include "display/display-object-container.h"
#include "motion/animator.hpp"

namespace tmlib {

    namespace display {


        class FreeList : public DisplayObjectContainer
        {
        public :
            FreeList() : _activeObj(NULL)
            {
                _animator.motion()->duration(10);
            }

            static bool onStartLerpCursor(events::Event* e)
            {
                DisplayObject* target = (DisplayObject*)(e->getTarget());
                FreeList* free_list = (FreeList*)(target->parent());
                free_list->lerpCursor(target);

                return true;
            }

            FreeList* addItem(DisplayObject* item)
            {
                addChild(item);
                item->addEventListener(events::EventInfo::CLICK, onStartLerpCursor);

                return this;
            }

            FreeList* setCursorPos(u32 index)
            {
                _activeObj = getChild(index);
                _activeObj->dispatchEvent(events::EventInfo::CLICK);
                return this;
            }

            FreeList* setCursorObject(DisplayObject* cursor)
            {
                _cursor = cursor;
                _animator.target(_cursor);
                return this;
            }

            void update()
            {
                DisplayObjectContainer::update();

                _animator.update();
            }

        protected :
            void lerpCursor(DisplayObject* target)
            {
                if (_activeObj == NULL) { _activeObj = getChild(0); }

                _animator.motion()->setValue(0, motion::AnimationInfo::X, _activeObj->x())->setValue(0, motion::AnimationInfo::Y, _activeObj->y());
                _animator.motion()->setValue(1, motion::AnimationInfo::X, target->x())->setValue(1, motion::AnimationInfo::Y, target->y());
                _animator.play();

                _activeObj = target;
            }

        private :
            DisplayObject*  _cursor;
            DisplayObject*  _activeObj;
            motion::Animator        _animator;
        };




        
        class SimpleGauge : public DisplayObject
        {
        public :
            SimpleGauge() : _max(10), _min(0), _sizeW(100), _sizeH(20), _loopFlag(false) {}

            SimpleGauge* setSize(f32 w, f32 h)
            {
                _sizeW = w; _sizeH = h;
                refresh();

                return this;
            }

            s32 value()
            {
                f32 len = pieceLength();
                return (s32)(width() / len) + _min;
            }

            SimpleGauge* value(s32 n)
            {
                if (_loopFlag == true) {
                    s32 temp = n + _min;
                    s32 len = _max - _min;

                    temp += len;
                    temp %= len;
                    temp -= _min;
                    n = temp;
                }
                else {
                    if (n < _min) { n=_min; }
                    if (n > _max) { n=_max; }
                }

                width( (n+_min)*pieceLength() );

                return this;
            }

        protected :
            f32 pieceLength()
            {
                return _sizeW / (float)(_max - _min);
            }
            void refresh()
            {
                s32 v = value();
                width(v*pieceLength());
            }

        private :
            s32 _max;
            s32 _min;
            f32 _sizeW, _sizeH;
            bool _loopFlag;
        };
    }

}